package com.mrrightli.nettty.gateway.outbound.netty4;

import com.mrrightli.nettty.gateway.filter.HeaderHttpResponseFilter;
import com.mrrightli.nettty.gateway.filter.HttpResponseFilter;
import com.mrrightli.nettty.gateway.router.HttpEndpointRouter;
import com.mrrightli.nettty.gateway.router.RandomHttpEndpointRouter;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

public class NettyHttpClient {

    private CloseableHttpAsyncClient httpclient;
    private ExecutorService proxyService;
    private List<String> backendUrls;
    private String uri;

    HttpResponseFilter filter = new HeaderHttpResponseFilter();
    HttpEndpointRouter router = new RandomHttpEndpointRouter();


    public NettyHttpClient(String backends) {
        this.uri = backends;
    }

    private String formatUrl(String backend) {
        return backend.endsWith("/")?backend.substring(0,backend.length()-1):backend;
    }

    public void connect(String host, int port) throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    // 客户端接收到的是httpResponse响应，所以要使用HttpResponseDecoder进行解码
                    ch.pipeline().addLast(new HttpResponseDecoder());
//                     客户端发送的是httprequest，所以要使用HttpRequestEncoder进行编码
                    ch.pipeline().addLast(new HttpRequestEncoder());
                    ch.pipeline().addLast(new NettyHttpClientOutboundHandler(uri));
                }
            });

            // Start the client.
            ChannelFuture f = b.connect(host, port).sync();

            String request = "{\"key\": \"hello netty http client\"}";
            f.channel().write(request);
            f.channel().flush();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }

    }

    public static void main(String[] args) throws Exception {

        NettyHttpClient client = new NettyHttpClient("/api/hello");
        client.connect("127.0.0.1", 8888);
    }
}
